package com.carter.springframework.core.annotation;

import com.sun.istack.internal.Nullable;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.function.Predicate;

public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>>{
    <A extends Annotation> MergedAnnotation<A> get(Class<A> annotationType);

    <A extends Annotation> MergedAnnotation<A> get(Class<A> annotationType, @Nullable Predicate<? super MergedAnnotation<A>> predicate);

    <A extends Annotation> MergedAnnotation<A> get(Class<A> annotationType, @Nullable Predicate<? super MergedAnnotation<A>> predicate, @Nullable MergedAnnotationSelector<A> selector);

    <A extends Annotation> MergedAnnotation<A> get(String annotationType);

    <A extends Annotation> MergedAnnotation<A> get(String annotationType, @Nullable Predicate<? super MergedAnnotation<A>> predicate);

    <A extends Annotation> MergedAnnotation<A> get(String annotationType, @Nullable Predicate<? super MergedAnnotation<A>> predicate, @Nullable MergedAnnotationSelector<A> selector);

    boolean isDirectlyPresent(String annotationType);

    /**
     * 实例化TypeMappedAnnotations
     * @param element 查找的AnnotatedElement
     * @param searchStrategy 搜索策略
     * @param repeatableContainers 可重复注解容器
     * @return
     */
    static MergedAnnotations from(AnnotatedElement element, SearchStrategy searchStrategy, RepeatableContainers repeatableContainers) {
        return TypeMappedAnnotations.from(element, searchStrategy, repeatableContainers, AnnotationFilter.PLAIN);
    }

    /**
     *
     * 实例化TypeMappedAnnotations
     * @param element 查找的AnnotatedElement
     * @param searchStrategy 搜索策略
     * @param repeatableContainers 可重复注解容器
     * @param annotationFilter 注解过滤器
     * @return
     */
    static MergedAnnotations from(AnnotatedElement element,SearchStrategy searchStrategy,RepeatableContainers repeatableContainers,AnnotationFilter annotationFilter){
        return TypeMappedAnnotations.from(element, searchStrategy, repeatableContainers, annotationFilter);
    }

    enum SearchStrategy {
        //只查找元素上直接声明的注解，不包括通过@Inherited继承的注解
        DIRECT,

        //只查找元素直接声明或通过@Inherited继承的注解
        INHERITED_ANNOTATIONS,

        //查找元素直接声明或所有父类的注解
        SUPERCLASS,

        //查找元素、所有父类以及实现的父接口的全部注解
        TYPE_HIERARCHY,

        //查找查找元素、所有父类以及实现的父接口、封闭类以及其子类的全部注解
        TYPE_HIERARCHY_AND_ENCLOSING_CLASSES
    }
}
